package main

import (
	"mygindemo/db"
	"mygindemo/router"
	"mygindemo/util"
	"net/http"

	"github.com/ahviplc/GoJustToolc/UConsole"
	"github.com/gin-gonic/gin"
)

var dbMap = make(map[string]string)

func setupRouter() *gin.Engine {
	// Disable Console Color
	// gin.DisableConsoleColor()
	r := gin.Default()

	// 允许跨域
	r.Use(util.Cors())

	// Ping test
	r.GET("/ping", func(c *gin.Context) {
		c.String(http.StatusOK, "pong")
	})

	// Get user value
	r.GET("/user/:name", func(c *gin.Context) {
		user := c.Params.ByName("name")
		value, ok := dbMap[user]
		if ok {
			c.JSON(http.StatusOK, gin.H{"user": user, "value": value})
		} else {
			c.JSON(http.StatusOK, gin.H{"user": user, "status": "no value"})
		}
	})

	// Authorized group (uses gin.BasicAuth() middleware)
	// Same than:
	// authorized := r.Group("/")
	// authorized.Use(gin.BasicAuth(gin.Credentials{
	//	  "foo":  "bar",
	//	  "manu": "123",
	//}))
	authorized := r.Group("/", gin.BasicAuth(gin.Accounts{
		"foo":  "bar", // user:foo password:bar
		"manu": "123", // user:manu password:123
	}))

	authorized.POST("admin", func(c *gin.Context) {
		user := c.MustGet(gin.AuthUserKey).(string)

		// Parse JSON
		var json struct {
			Value string `json:"value" binding:"required"`
		}

		if c.Bind(&json) == nil {
			dbMap[user] = json.Value
			c.JSON(http.StatusOK, gin.H{"status": "ok"})
		}
	})

	// LC Diy ====================================================

	// root test
	r.GET("/", router.Root)

	//v1组路由
	v1 := r.Group("/v1")
	{
		v1.GET("/hello", router.Hello1)
	}

	//v2组路由
	v2 := r.Group("/v2")
	{
		v2.GET("/hello", router.Hello2)
	}

	// hello3 test
	r.GET("/hello", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"message": "hello world",
		})
	})

	// findFirstOneUser
	r.GET("/findFirstOneUser", router.FindFirstOneUser)

	// findAllUsers
	r.GET("/findAllUsers", router.FindAllUsers)

	// Gin框架支持开发RESTful API的开发 以下是设计
	// GET
	r.GET("/user", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "GET user",
		})
	})
	// POST
	r.POST("/user", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "POST user",
		})
	})
	// PUT
	r.PUT("/user", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "PUT user",
		})
	})
	// DELETE
	r.DELETE("/user", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "DELETE user",
		})
	})

	// Any
	r.Any("/user2", func(c *gin.Context) {
		UConsole.Log("[info]user2请求方法:", c.Request.Method)
		switch c.Request.Method {
		case http.MethodGet:
			c.JSON(200, gin.H{
				"message": "Get user2",
			})
		case "POST":
			c.JSON(200, gin.H{
				"message": "POST user2",
			})
		case http.MethodPut:
			c.JSON(200, gin.H{
				"message": "PUT user2",
			})
		case http.MethodDelete:
			c.JSON(200, gin.H{
				"message": "DELETE user2",
			})
		case http.MethodHead: // HEAD和GET本质是一样的，区别在于HEAD不含有呈现数据，而仅仅是HTTP头信息。有的人可能觉得这个方法没什么用，其实不是这样的。想象一个业务情景：欲判断某个资源是否存在，我们通常使用GET，但这里用HEAD则意义更加明确
			c.JSON(200, gin.H{
				"message": "HEAD user2",
			})
		case http.MethodOptions:
			c.JSON(200, gin.H{
				"message": "Options user2",
			})
		default:
			c.JSON(200, gin.H{
				"message": c.Request.Method + " user2 未定义",
			})
		}
	})

	// HTML渲染
	// 配置加载html的路径
	//r.LoadHTMLGlob("templates/*") // templates下所有的html
	r.LoadHTMLGlob("templates/**/*") // templates下多级目录下所有的html
	// r.LoadHTMLFiles("templates/posts/index.html", "templates/users/index.html") // 如果只是加载两个 这样写也可
	// 配置静态文件路径
	r.Static("/static", "static")
	// 查询第一个用户
	r.GET("users/one", func(c *gin.Context) {
		UConsole.PrintAStraightLine()
		UConsole.PrintTypeAndValue(db.FindFirstOneUserDB())
		UConsole.PrintAStraightLine()
		c.HTML(http.StatusOK, "users/indexOneUser.html", db.FindFirstOneUserDB())
	})
	// 跳转到展示所有用户的页面 todo 无数据呢
	r.GET("users/page", func(c *gin.Context) {
		c.HTML(http.StatusOK, "users/indexAllUsersVue.html", gin.H{
			"title": "users/indexAllUsersVue",
		})
	})
	// 查询全部用户api
	r.GET("users/all", func(c *gin.Context) {
		// 返回json
		c.JSON(http.StatusOK, db.FindAllUsersDB())
	})

	// 路由重定向
	r.GET("/test", func(c *gin.Context) {
		// 指定重定向的URL
		// c.Request.URL.Path = "/users/page"
		c.Request.URL.Path = "/test2"
		r.HandleContext(c)
	})
	r.GET("/test2", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"hello": "world test2"})
	})

	// HTTP重定向
	r.GET("/test3", func(c *gin.Context) {
		c.Redirect(http.StatusMovedPermanently, "https://www.liwenzhou.com/")
	})
	// LC Diy ====================================================
	return r
}

func main() {
	// 执行gin逻辑
	r := setupRouter()
	// Listen and Server in 0.0.0.0:9091
	r.Run(":9091")
}
